package elicecn.util.encrypt;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;

import elicecn.util.DigitalUtils;

/**
 * {@link Encrypt}接口基于消息摘要算法的默认实现。它没有实现任何算法，仅实现了消息摘要计算过程方法。
 * 在继承此类时，需要设置消息摘要算法对象，以实现消息摘要算法。
 * 
 * @author 屹砾
 * @email eli.wuhan@gmail.com
 * @time 2009-3-1
 */
public class MessageDigest extends EncryptBase {
	private static final long serialVersionUID = -3669353076872781993L;
	/**
	 * 消息摘要算法对象
	 */
	protected java.security.MessageDigest messageDigest = null;

	public MessageDigest(java.security.MessageDigest messageDigest) {
		this.messageDigest = messageDigest;
	}

	/**
	 * 使用指定的字符数组或输入流进行摘要计算。
	 * 
	 * @param is
	 *            输入流
	 * @return 存放哈希值结果的十六进制数字字符串。
	 * @throws IOException
	 *             如果发生 I/O 错误(在使用输入流进行摘要计算时可能抛出此异常)。
	 */
	protected String calculate(InputStream is) throws IOException {
		int idx = 0;
		byte[] result = null;
		BufferedInputStream bis = new BufferedInputStream(is, BUFFER_SIZE);
		byte[] bt = new byte[BUFFER_SIZE];
		synchronized (messageDigest) {
			while ((idx = bis.read(bt)) != -1) {
				messageDigest.update(bt, 0, idx);
			}
			result = messageDigest.digest();
		}
		is.close();
		bis.close();
		String code = new String(DigitalUtils.toHex(result));
		return code;
	}

}
